﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using WiimoteLib;

namespace WiiPresenter {
    /// <summary>
    /// Interaction logic for ZoomWindow.xaml
    /// </summary>
    public partial class ZoomWindow : Window {
        ScaleTransform mScaleTransform;
        const double ScaleFactorDelta = 0.1;
        const int MoveFactor = 48;
        double mCurrentScaleFactor = 1;
        double mScaledMoveFactor;

        static protected ZoomWindow mCurrentWindow;
        static public ZoomWindow CurrentWindow {
            get { return mCurrentWindow; }
        }

        public ZoomWindow() {
            InitializeComponent();
            mCurrentWindow = this;

            inkcAnnotate.DefaultDrawingAttributes.Color = Colors.Cyan;

            Closed += new EventHandler(ZoomWindow_Closed);
            PreviewKeyDown += new KeyEventHandler(ZoomWindow_PreviewKeyDown);
        }

        public void WiimoteStatus(WiimoteState aState) {
            if (aState.ButtonState.Minus) {
                ZoomOut();
            }
            if (aState.ButtonState.Home) {
                ZoomReset();
            }
            if (aState.ButtonState.Plus) {
                ZoomIn();
            }
            if (aState.ButtonState.A) {
                Quit();
            }
            if (aState.ButtonState.One) {
                ClearAnnotations();
            }
            if (aState.ButtonState.Up) {
                ScrollUp();
            }
            if (aState.ButtonState.Down) {
                ScrollDown();
            }
            if (aState.ButtonState.Left) {
                ScrollLeft();
            }
            if (aState.ButtonState.Right) {
                ScrollRight();
            }
        }

        void Quit() {
            Close();
        }

        void ClearAnnotations() {
            inkcAnnotate.Strokes.Clear();
        }

        void ZoomIn() {
            Scale(1 + ScaleFactorDelta);
        }

        void ZoomOut() {
            Scale(1 - ScaleFactorDelta);
        }

        void ZoomReset() {
            Scale(0);
        }

        void ScrollUp() {
            mScaleTransform.CenterY = Math.Max(0, mScaleTransform.CenterY - mScaledMoveFactor);
        }

        void ScrollDown() {
            mScaleTransform.CenterY = Math.Min(imagZoom.ActualHeight, mScaleTransform.CenterY + mScaledMoveFactor);
        }

        void ScrollLeft() {
            mScaleTransform.CenterX = Math.Max(0, mScaleTransform.CenterX - mScaledMoveFactor);
        }

        void ScrollRight() {
            mScaleTransform.CenterX = Math.Min(imagZoom.ActualWidth, mScaleTransform.CenterX + mScaledMoveFactor);
        }

        void ZoomWindow_PreviewKeyDown(object sender, KeyEventArgs e) {
            if (e.Key == Key.Escape) {
                Quit();
            } else if (e.Key == Key.Delete) {
                ClearAnnotations();
            } else if (e.Key == Key.Home) {
                ZoomReset();
            } else if (e.Key == Key.Add || e.Key == Key.OemPlus || e.Key == Key.PageUp) {
                ZoomIn();
            } else if (e.Key == Key.Subtract || e.Key == Key.OemMinus || e.Key == Key.PageDown) {
                ZoomOut();
            } else if (e.Key == Key.Up) {
                ScrollUp();
            } else if (e.Key == Key.Down) {
                ScrollDown();
            } else if (e.Key == Key.Left) {
                ScrollLeft();
            } else if (e.Key == Key.Right) {
                ScrollRight();
            }
        }

        void Scale(double aFactor) {
            if (aFactor == 0) {
                mCurrentScaleFactor = 1;
            } else {
                if (mScaleTransform.ScaleX == 1 && aFactor > 0) {
                    var xMouseLoc = Mouse.GetPosition(imagZoom);
                    mScaleTransform.CenterX = xMouseLoc.X;
                    mScaleTransform.CenterY = xMouseLoc.Y;
                }
                mCurrentScaleFactor = Math.Max(1, mScaleTransform.ScaleX * aFactor);
            }
            mScaleTransform.ScaleY = mScaleTransform.ScaleX = mCurrentScaleFactor;
            mScaledMoveFactor = MoveFactor / mCurrentScaleFactor;
        }

        void ZoomWindow_Closed(object sender, EventArgs e) {
            mCurrentWindow = null;
        }

        void Display() {
            var xBitmap = Win32.GetDesktopWindowCaptureAsBitmap();
            var xScreenShot = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(xBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty
                , System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
            imagZoom.Source = xScreenShot;

            mScaleTransform = new ScaleTransform();
            inkcAnnotate.RenderTransform = mScaleTransform;

            Show();
        }

        static public void Start() {
            if (mCurrentWindow == null) {
                new ZoomWindow();
            }
            mCurrentWindow.Display();
        }

    }
}
